package org.m2acsi.entities;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
import javax.validation.constraints.Size;
import org.m2acsi.utils.PrettyDate;

@Entity(name = "Documents")
public class Document implements Serializable {

    private Long id;
    private String name;
    private String mongoId;
    private Opinion opinion;
    private Task task;
    private Upload upload;
    private List<Download> downloads;
    private boolean isNew;

    public Document() {
        this.downloads = new ArrayList<>();
    }

    public Document(String name, String mongoId) {
        this();
        this.name = name;
        this.mongoId = mongoId;
    }

    public Document(String name, String mongoId, Task task, Upload upload) {
        this(name, mongoId);
        this.task = task;
        this.upload = upload;
    }

    public Document(String name, String mongoId, Opinion opinion, Upload upload) {
        this(name, mongoId);
        this.opinion = opinion;
        this.upload = upload;
    }

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    @Size(min = 1, max = 100)
    @Column(nullable = false, updatable = false, length = 100)
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    @Column(nullable = false, updatable = true)
    public String getMongoId() {
        return mongoId;
    }

    public void setMongoId(String mongoId) {
        this.mongoId = mongoId;
    }

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "document", optional = true)
    @JoinColumn(nullable = true, updatable = false)
    public Opinion getOpinion() {
        return opinion;
    }

    public void setOpinion(Opinion opinion) {
        this.opinion = opinion;
    }

    @ManyToOne
    @JoinColumn(name = "TASK_ID", nullable = true, updatable = false)
    public Task getTask() {
        return task;
    }

    public void setTask(Task task) {
        this.task = task;
    }

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false)
    @JoinColumn(nullable = false, updatable = false)
    public Upload getUpload() {
        return upload;
    }

    public void setUpload(Upload upload) {
        this.upload = upload;
    }

    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "document")
    public List<Download> getDownloads() {
        return downloads;
    }

    public void setDownloads(List<Download> downloads) {
        this.downloads = downloads;
    }

    @Override
    public String toString() {
        return "Document{" + "id=" + id + ", name=" + name + ", mongoId=" + mongoId + ", taskTitle=" + task.getTitle() + ", userUpload=" + upload.getUploader() + '}';
    }

    public String getPrettyCreationDate() {
        return PrettyDate.niceCreation(upload.getCreationDate());
    }

    @Transient
    public boolean getIsNew() {
        return isNew;
    }

    public void setIsNew(boolean isNew) {
        this.isNew = isNew;
    }

    public String getNewLabel() {
        return isNew ? "new" : "";
    }
}
